package com.xielun.fly.framework.sql;

import com.xielun.fly.framework.Constants;
import com.xielun.fly.framework.Node;

import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * User: xzs
 * Date: 2017/9/28
 * Time: 11:53
 * To change this template use File | Settings | File Templates.
 */
public class SQL {
    private List<String> columns = new ArrayList<String>();
    private Map<String, Object> conditions = new LinkedHashMap();
    private Map<String, Object> data = new LinkedHashMap();//跟新时，data和conditions需要区分
    private Map<String, Object> groups = new LinkedHashMap();
    private Map<String, Object> havings = new LinkedHashMap();
    private Map<String, Object> orders = new LinkedHashMap();
    private int page = 1;
    private int size = 10;

    private String sql;
    private String table;

    private String operate;
    private boolean isDataArray;//是否是数组数据 key[]

    public void bind(Node node) {
        String nodeKey = node.getKey();
        table = nodeKey.replaceAll("^\\+|^\\-|^\\*|(\\[\\])$", "");
        operate = nodeKey.substring(0, 1);
        isDataArray = nodeKey.endsWith("[]");
        for (Map.Entry<String, Object> entry : node.getMeta().entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            if (!(value instanceof Map)) {
                if (Constants.PAGE.equals(key)) {
                    page = Integer.parseInt(value + "");
                    continue;
                }
                if (Constants.SIZE.equals(key)) {
                    size = Integer.parseInt(value + "");
                    continue;
                }
                if (key.equals(Constants.COLUMN)) {
                    columns = Arrays.asList((value + "").split(","));
                    continue;
                }
                if (key.startsWith("$")) {
                    data.put(key.replace("$", ""), value);
                    continue;
                }
                if (key.equals(Constants.ORDER)) {
                    //id-,name = id desc,name asc
                    for (String s : Arrays.asList((value + "").split(","))) {
                        if (s.endsWith("-")) {
                            orders.put(s.substring(0, s.length() - 1), "desc");
                        } else {
                            orders.put(s, "asc");
                        }
                    }
                    continue;
                }
                if ((value + "").startsWith("@")) {
                    String val = (value + "").replace("@", "");
                    String[] a = val.split("/");
                    int len = a.length;
                    Node targetNode = node.getParent();
                    for (int i = 0; i < len - 1; i++) {
                        if ("..".equals(a[i])) {
                            targetNode = targetNode.getParent();
                        } else if ("".equals(a[i])) {
                            targetNode = node.getRoot();
                        } else {
                            for (Node child : targetNode.getChilds()) {
                                if (child.getKey().equals(a[i])) {
                                    targetNode = child;
                                    break;
                                }
                            }
                        }
                    }
                    targetNode.getData();
                    value = targetNode.getTemData().get(a[len - 1]);
                    conditions.put(key, value);
                    continue;
                }
                conditions.put(key, value);
            }
        }


    }

    public String getColumnsStr() {
        StringBuilder sqlBuilder = new StringBuilder();
        if (columns.size() == 0) {
            return " * ";
        }
        for (String name : columns) {
            sqlBuilder.append(name);
            if (!name.equals(columns.get(columns.size() - 1))) {
                sqlBuilder.append(",");
            }
        }
        return sqlBuilder.toString();
    }


    public String getWhere() {
        StringBuilder sqlBuilder = new StringBuilder();
        if (conditions.size() == 0) {
            return "";
        }
        boolean isFirst = true;
        for (Map.Entry<String, Object> entry : conditions.entrySet()) {
            String key = entry.getKey();
            sqlBuilder.append((isFirst ? " WHERE " : " AND ") + key + "=" + getRealValue(entry.getValue()));
            isFirst = false;
        }
        return sqlBuilder.toString();
    }

    private String getRealValue(Object value) {
        if (value instanceof String) {
            return "'" + value + "'";
        }
        return value + "";
    }

    public Map<String, Object> getData() {
        return data;
    }

    public void setData(Map<String, Object> data) {
        this.data = data;
    }

    public List<String> getColumns() {
        return columns;
    }

    public void setColumns(List<String> columns) {
        this.columns = columns;
    }

    public Map<String, Object> getConditions() {
        return conditions;
    }

    public void setConditions(Map<String, Object> conditions) {
        this.conditions = conditions;
    }

    public Map<String, Object> getGroups() {
        return groups;
    }

    public void setGroups(Map<String, Object> groups) {
        this.groups = groups;
    }

    public Map<String, Object> getHavings() {
        return havings;
    }

    public void setHavings(Map<String, Object> havings) {
        this.havings = havings;
    }

    public Map<String, Object> getOrders() {
        return orders;
    }

    public void setOrders(Map<String, Object> orders) {
        this.orders = orders;
    }

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public String getSql() {
        return sql;
    }

    public boolean isDataArray() {
        return isDataArray;
    }

    public void setDataArray(boolean dataArray) {
        isDataArray = dataArray;
    }

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }

    public void setSql(String sql) {
        this.sql = sql;
    }

    public String getTable() {
        return table;
    }

    public void setTable(String table) {
        this.table = table;
    }

    public String getOperate() {
        return operate;
    }

    public void setOperate(String operate) {
        this.operate = operate;
    }

    public static void main(String[] args) {
        System.out.println("[]eus+-er[]".replaceAll("^\\+|^\\-|^\\*|(\\[\\])$", ""));
    }


    public String getOrderStr() {
        if (orders.size() == 0) {
            return "";
        }
        StringBuilder sqlBuilder = new StringBuilder();
        boolean isFirst = true;
        for (Map.Entry<String, Object> entry : conditions.entrySet()) {
            String key = entry.getKey();
            sqlBuilder.append((isFirst ? " ORDER BY " : " , ") + key + "=" + entry.getValue());
            isFirst = false;
        }
        return sqlBuilder.toString();
    }

    public String getPageStr() {
        StringBuilder sqlBuilder = new StringBuilder();

        sqlBuilder.append(" LIMIT " + (page - 1) * size + "," + size);
        return sqlBuilder.toString();

    }

    public String getDataStr() {
        StringBuilder sqlBuilder = new StringBuilder();
        boolean isFirst = true;
        for (Map.Entry<String, Object> entry : data.entrySet()) {
            String key = entry.getKey();
            sqlBuilder.append((isFirst ? " SET " : " , ")+key + "=" + getRealValue(entry.getValue()));
            isFirst = false;
        }
        return sqlBuilder.toString();
    }

    public String getInsertDataStr() {
        StringBuilder sqlBuilder = new StringBuilder();
        boolean isFirst = true;
        final Set<String> names = conditions.keySet();
        /*********************插入的属性*****************************/
        for (String name : names) {
            sqlBuilder.append((isFirst ? " ( " : " , ")+name);
            isFirst = false;
        }
        sqlBuilder.append(")");

        /*************插入的值**************************************/
        isFirst = true;
        for (String name : names) {
            sqlBuilder.append((isFirst ? " VALUES(" : " , ")+getRealValue(conditions.get(name)));
            isFirst = false;
        }
        sqlBuilder.append(")");

        return sqlBuilder.toString();
    }


}
